home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 287_01 / gradprog.doc < prev   
Encoding:
Text File  |  1989-05-23  |  31.1 KB  |  1,233 lines

  1.  
  2.  
  3.  
  4.  
  5.        
  6.                        GRAD Programmers' Reference Manual
  7.                                         
  8.                                 Table Of Content
  9.        
  10.        
  11.        1   Introduction . . . . . . . . . . . . . . . . . . . . . .    1
  12.        2   Basic Philosophy . . . . . . . . . . . . . . . . . . . .    2
  13.        3   calcaddr and plottype  . . . . . . . . . . . . . . . . .    3
  14.           3.1  calcaddr . . . . . . . . . . . . . . . . . . . . . .    3
  15.           3.2  plottype . . . . . . . . . . . . . . . . . . . . . .    3
  16.        4   Frame Table  . . . . . . . . . . . . . . . . . . . . . .    4
  17.        5   Font Table . . . . . . . . . . . . . . . . . . . . . . .    5
  18.        6   HorzLine, VertLine and Line  . . . . . . . . . . . . . .    6
  19.           6.1  HorzLine . . . . . . . . . . . . . . . . . . . . . .    6
  20.           6.2  VertLine . . . . . . . . . . . . . . . . . . . . . .    6
  21.           6.3  Line . . . . . . . . . . . . . . . . . . . . . . . .    7
  22.        7   Circle, Ellipse and Arc  . . . . . . . . . . . . . . . .    9
  23.           7.1  Circle . . . . . . . . . . . . . . . . . . . . . . .    9
  24.           7.2  Ellipse  . . . . . . . . . . . . . . . . . . . . . .   10
  25.           7.3  Arc  . . . . . . . . . . . . . . . . . . . . . . . .   11
  26.        8   Text Writing . . . . . . . . . . . . . . . . . . . . . .   12
  27.        9   Region Filling . . . . . . . . . . . . . . . . . . . . .   13
  28.        10  Block Copy, Save and Load  . . . . . . . . . . . . . . .   15
  29.        11  Writing Graphics Display Adapter Driver  . . . . . . . .   16
  30.        12  Writing Printer Driver . . . . . . . . . . . . . . . . .   17
  31.        13  Hints on Porting to Other C Compiler or Other Machine  .   18
  32.        
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.                        GRAD Programmers' Reference Manual
  69.  
  70.        1   Introduction
  71.        
  72.             The source code of the GRAD library are coyrighted. However
  73.        you  are  free  to modify and re-distribute the source files for
  74.        non-commerical  use  and  you indiciate the files are originated 
  75.        from the GRAD library.
  76.             
  77.             If you find and bugs in the GRAD routines, please inform me.
  78.        Your help will be appreciated.
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.                                                                         1
  126.  
  127.  
  128.  
  129.                        GRAD Programmers' Reference Manual
  130.  
  131.        2   Basic Philosophy
  132.        
  133.             The idea of GRAD  system come to  me about 1  year ago (1986
  134.        summer). At that time, I want to write a program that can produce
  135.        high quality,  high speed full page  text and  graphics print out
  136.        suitable for report on a dot matrix printer.
  137.             
  138.             In order to  produce high  quality text  output,  bit mapped
  139.        character must be able to be loaded and included in the print out
  140.        as  graphics  data.  However printing a full  page  of bit mapped
  141.        graphics data on a dot matrix printer may take  5  to 15 minutes.
  142.        So  all normal  text  should be printed in  NLQ text  mode of the
  143.        printer instead of in graphics mode.
  144.             
  145.             Furthermore 2  types of graphics data may be included in the
  146.        print out.  First type is that the graphics  data  are already in
  147.        bit mapped format.  Another type is that the graphics data are in
  148.        high level command format  such  as circles,  lines and dots. The
  149.        advantages of second type are that the graphics data file size is
  150.        relatively small unless the drawing is very complicated. Further-
  151.        more and the drawings may be changed easily.
  152.             
  153.             Very  quickly,  I realized  that  this  program is  not that
  154.        simple.  As the first phase of implementation, a graphics library
  155.        is written which is the GRAD system. The sample program MPrint is
  156.        a simplified version of my original idea.
  157.             
  158.             
  159.             In GRAD,  you may divide the routines into different layers.
  160.        Layer  0  contains routines that directly deal with  the hardware
  161.        (including  memory).   Hence  layer   0   routines  are  hardware
  162.        dependent.  The  number  of routines in  this layer is kept  to a
  163.        minimum.   Layer  1  routines  accepts  physical  coordinates  as
  164.        parameters. No external GRAD functions are in this layer. Most of
  165.        this routines  are written in  assembly  language. GRAD functions
  166.        usually  spend most  of  them  in  this  layer of  codes. Layer 2
  167.        routines handles translation of  logical coordinates  to physical
  168.        coordinates and also clipping  of drawings under  current defined
  169.        window.  Most  of  these routines are  written in C.  Most of the
  170.        layer  2  routines call layer  1  routines to do actual drawings.
  171.        However there are some exception cases that layer 2 routines call
  172.        layer 0  routines directly.  But none of the routines  in layer 1
  173.        and layer 2 access hardware directly.
  174.             
  175.             There are also  some  functions  that  do  not  requires any
  176.        coordinates in the parameter  such as PlotType and ResetWin. They
  177.        are called system functions and do not belong  to any  one of the
  178.        above layers.
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.                                                                         2
  191.  
  192.  
  193.  
  194.                        GRAD Programmers' Reference Manual
  195.  
  196.        3   calcaddr and plottype
  197.        
  198.        3.1  calcaddr
  199.        
  200.             $calc and downln  are the two main  routines  in  the module
  201.        calcaddr. There are also some hardware dependent routines such as
  202.        settext  and setgraph  but they  would  not be discussed  in this
  203.        manual.
  204.             
  205.             $calc accepts x and y coordinates  in  register  AX  and BX.
  206.        Segment and offset values are returned in AX and BX respectively.
  207.        The  return  address a far address that  means the  segment value
  208.        should not be changed because the segment value may  be a logical
  209.        number only  and not a actual  segment number.  The  offset value
  210.        must be a even number and it must  be set  up in such  a way that
  211.        the  whole line  containing  the point  x,y  can  be  accessed by
  212.        changing the offset value only.
  213.             
  214.             downln accepts  the address of  a frame in  ES:BX and return
  215.        the address of the next line with  the same number of  words from
  216.        the beginning  of the line.  This is used to speed up drawings in
  217.        vertical direction such as VertLine.
  218.        
  219.        
  220.        3.2  plottype
  221.        
  222.             The module plottype contain routines  that  access the frame
  223.        memory using the address returned  by $calc and  downln. There is
  224.        nothing fancy so the comment in the module should be sufficient.
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.                                                                         3
  256.  
  257.  
  258.  
  259.                        GRAD Programmers' Reference Manual
  260.  
  261.        4   Frame Table
  262.        
  263.             In  the frame table,  it  contains  all information  about a
  264.        frame.  Information include starting address of  the frame, frame
  265.        width in byte,  horizontal and vertical size,  logical origin and
  266.        the window defined in  that frame.
  267.             
  268.             The  number of entries in  frame table controls  the maximum
  269.        number of frame that can be existed in GRAD system. The number of
  270.        entry in the  frame table is  control by the  value NFRAME during
  271.        compilation time. The default value of NFRAME is 10.
  272.             
  273.             The structure of  the frame table may be  changed  in future
  274.        version.  So do not make any assumption about  the relative order
  275.        of the variables inside the structure in your routines.
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.                                                                         4
  321.  
  322.  
  323.  
  324.                        GRAD Programmers' Reference Manual
  325.  
  326.        5   Font Table
  327.        
  328.             Font  table contains  information  about  each  font loaded.
  329.        Information  include the font  type (fix size  or variable size),
  330.        lowest code and highest  code number,  the default character code
  331.        and  also  pointers  to  the  pattern  and  individual  character
  332.        information.
  333.             
  334.             Individual  character  information  include  width,  height,
  335.        inkwidth,  cellheight,  leftmargin and topline. This is one entry
  336.        for fix size font and one entry per character  for  variable size
  337.        font.
  338.             
  339.             There  is also an  additional array of pointers  pointing to
  340.        pattern of individual characters for variable size font. The font
  341.        table contains the pointer to the array of pointers.
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.                                                                         5
  386.  
  387.  
  388.  
  389.                        GRAD Programmers' Reference Manual
  390.  
  391.        6   HorzLine, VertLine and Line
  392.        
  393.        6.1  HorzLine
  394.        
  395.             The C code  can be  used  to  replace  the  assembly routine
  396.        horzl. It uses the same algorithm as horzl.
  397.        
  398.            horzl(x,y,length)
  399.            int x,y,length;
  400.            {
  401.              int far *addr;
  402.              unsigned int pword;
  403.              int len,loop;
  404.            
  405.              addr=calcaddr(x,y);
  406.              len = (x & 0x0f) + length;
  407.              if (len <= 16) {
  408.                pword=LEFTWORD[x & 0x0f] ^ LEFTWORD[len];
  409.                fr_write(addr,pword);
  410.                return;
  411.                }
  412.              fr_write(addr,LEFTWORD[x & 0x0f]);
  413.              addr++;
  414.              for (loop=len >> 4; loop > 1; loop--,addr++)
  415.                fr_write(addr,0xffff);
  416.              fr_write(addr,RIGHTWORD[len & 0x0f]);
  417.            }
  418.        
  419.             The program should not be difficult to understand.
  420.        
  421.        
  422.        6.2  VertLine
  423.        
  424.             The C routine below is  functional equivalent to  vert1l. It
  425.        only draws a line 1 pixel wide.
  426.        
  427.            vertline(x,y,length)
  428.            int x,y,length;
  429.            {
  430.              int far *addr, far *downline();
  431.              unsigned int pword;
  432.              int loop;
  433.            
  434.              addr=calcaddr(x,y);
  435.              LASTY=y;
  436.              pword=DOTVALUE[x & 0x0f];
  437.              while (length-- > 0) {
  438.                fr_write(addr,pword);
  439.                addr=downline(addr);
  440.                }
  441.            }
  442.            
  443.             To draw a vertical line of 1 pixel wide is quite simple. But
  444.        when the width can be  any number  then  the routine  become much
  445.        more complicated.  The  routine  vertl  combines  both  horzl and
  446.        vert1l together.  The  downline  routine is not  included in GRAD
  447.        library so the code is listed below.
  448.            
  449.  
  450.                                                                         6
  451.  
  452.  
  453.  
  454.                        GRAD Programmers' Reference Manual
  455.  
  456.            _downline proc  near
  457.                    push    bp
  458.                    mov     bp,sp
  459.                    push    si
  460.                    les     bx,[bp+smo]
  461.                    call    downln
  462.                    mov     dx,es           ; result return in DX:AX
  463.                    mov     ax,bx
  464.                    pop     si
  465.                    pop     bp
  466.                    ret
  467.            _downline endp
  468.             
  469.        
  470.        
  471.        6.3  Line
  472.        
  473.             The algorithm used in drawing line is explained in  the book
  474.        "Fundamental of Interactive  Computer Graphics"  by Foley and Van
  475.        Dam p.433-436.  The C routine below can draw a line but there are
  476.        a lot of difference between this routine and the routine  in GRAD
  477.        library. So the one below is for reference only.
  478.             
  479.            line(x1,y1,x2,y2)
  480.            int x1,y1,x2,y2;
  481.            {
  482.              int dx,dy,d,x,y,xend,yend,len,incr1,incr2,xdir,ydir,dir;
  483.            
  484.              xdir=ydir=0;
  485.              if ((dx=x2-x1) < 0) { dx = -dx; xdir=(-1); }
  486.              if ((dy=y2-y1) < 0) { dy = -dy; ydir=(-1); }
  487.              if (dx == 0) {
  488.                if (xdir)
  489.                  vertline(x1,y2,++dy);
  490.                else
  491.                  vertline(x1,y1,++dy);
  492.                }
  493.              if (dy == 0) {
  494.                if (ydir)
  495.                  horzline(x1,y2,++dx);
  496.                else
  497.                  horzline(x1,y1,++dx);
  498.                }
  499.              if ((xdir==(-1)) && (ydir==(-1)))
  500.                dir=1;
  501.              else if (xdir || ydir)
  502.                dir=xdir+ydir;
  503.              else
  504.                dir=1;
  505.              if (dy <= dx) {
  506.                d = (dy << 1) - dx;
  507.                incr1 = dy << 1;
  508.                incr2 = (dy - dx) << 1;
  509.                if (xdir) {
  510.                  x=x2; y=y2; xend=x1;
  511.                  }
  512.                else {
  513.                  x=x1; y=y1; xend=x2;
  514.  
  515.                                                                         7
  516.  
  517.  
  518.  
  519.                        GRAD Programmers' Reference Manual
  520.  
  521.                  }
  522.                len=1;
  523.                while (x++<xend) {
  524.                  if (d<0) {
  525.                    d+=incr1;
  526.                    len++;
  527.                    }
  528.                  else {
  529.                    horzline(x-len,y,len);
  530.                    len=1;
  531.                    d+=incr2;
  532.                    y+=dir;
  533.                    }
  534.                  }
  535.                horzline(x-len,y,len);
  536.                }
  537.              else {
  538.                d = (dx << 1) - dy;
  539.                incr1 = dx << 1;
  540.                incr2 = (dx - dy) << 1;
  541.                if (ydir) {
  542.                  x=x2; y=y2; yend=y1;
  543.                  }
  544.                else {
  545.                  x=x1; y=y1; yend=y2;
  546.                  }
  547.                len=1;
  548.                while (y++<yend) {
  549.                  if (d<0) {
  550.                    d+=incr1;
  551.                    len++;
  552.                    }
  553.                  else {
  554.                    vertline(x,y-len,len);
  555.                    len=1;
  556.                    d+=incr2;
  557.                    x+=dir;
  558.                    }
  559.                  }
  560.                vertline(x,y-len,len);
  561.                }
  562.            }
  563.             
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.                                                                         8
  581.  
  582.  
  583.  
  584.                        GRAD Programmers' Reference Manual
  585.  
  586.        7   Circle, Ellipse and Arc
  587.        
  588.        7.1  Circle
  589.        
  590.             Because a circle is symmetrical so we only need to calculate
  591.        the  value  for  one-eight  of  a  circle  and  by  making simple
  592.        transformation of  the value  calculated,  we  may  draw  a whole
  593.        circle.  The program for drawing circle  is  very  simple but the
  594.        deriving process is not simple. You may find the algorithm in the
  595.        book "Fundamentals of Interactive Computer Graphics"  by Foley on
  596.        page 442-446.
  597.            
  598.            circle_pt(ctrx,ctry,x,y)
  599.            int ctrx,ctry,x,y;
  600.            {
  601.              dot(x+ctrx,y+ctry);
  602.              dot(y+ctrx,x+ctry);
  603.              dot(y+ctrx,-x+ctry);
  604.              dot(x+ctrx,-y+ctry);
  605.              dot(-x+ctrx,-y+ctry);
  606.              dot(-y+ctrx,-x+ctry);
  607.              dot(-y+ctrx,x+ctry);
  608.              dot(-x+ctrx,y+ctry);
  609.            }
  610.            
  611.            circle(centerx,centery,radius)
  612.            int centerx,centery,radius;
  613.            { 
  614.              register int x, d;
  615.              int y, incr1, incr2;
  616.            
  617.              x=0;
  618.              y=radius;
  619.              incr1=6;
  620.              incr2=10-(radius<<2);
  621.              d=3-(radius<<1);
  622.              while (x < y) {
  623.                circle_pt(centerx,centery,x++,y);
  624.                if (d<0) {
  625.                    d+=incr1;
  626.                    incr2+=4;
  627.                } else {
  628.                    d+=incr2;
  629.                    incr2+=8;
  630.                    y--;
  631.                }
  632.                incr1+=4;
  633.              }
  634.              if (x==y) circle_pt(centerx,centery,x,y);
  635.            }
  636.            
  637.             The program below is  equivalent to the circle  above except
  638.        it is shorter but slower.
  639.            
  640.            circle(centerx,centery,radius)
  641.            int centerx,centery,radius;
  642.            { 
  643.              int x,y,d;
  644.  
  645.                                                                         9
  646.  
  647.  
  648.  
  649.                        GRAD Programmers' Reference Manual
  650.  
  651.            
  652.              x=0;
  653.              y=radius;
  654.              d=3-(radius<<1);
  655.              while     (x < y) {
  656.                circle_pt(centerx,centery,x++,y);
  657.                d += (d < 0) ? (x << 2) + 6     : ((x - y--) << 2) + 10;
  658.                }
  659.              if (x==y) circle_pt(centerx,centery,x,y);
  660.            }
  661.        
  662.        
  663.        7.2  Ellipse
  664.        
  665.             The algorithm for ellipse is the much more  complicated than
  666.        circle. The equation is derived by myself using method similar to
  667.        that of the circle. The program below is a simplified version.
  668.             
  669.            ellipse_pt(ctrx,ctry,x,y)
  670.            int ctrx,ctry,x,y;
  671.            {
  672.              dot(x+ctrx,y+ctry);
  673.              dot(x+ctrx,-y+ctry);
  674.              dot(-x+ctrx,-y+ctry);
  675.              dot(-x+ctrx,y+ctry);
  676.            }
  677.            
  678.            ellipse(ctrx,ctry,a,b)
  679.            int ctrx,ctry,a,b;
  680.            {
  681.              long incr1,incr2,a2,b2,d,step1,step2,ptx,pty;
  682.              int x,y;
  683.            
  684.              x=0;
  685.              y=b;
  686.              a2= (long) a * a;
  687.              b2= (long) b * b;
  688.              step1 = a2 << 2;
  689.              step2 = b2 << 2;
  690.              d= ((b2 - (a2 * b)) << 1) + a2;
  691.              incr1= step2 + (b2 << 1);
  692.              incr2= step1 + step2 + (b2 << 1) - ((a2 * b) << 2);
  693.              ptx=0;
  694.              pty=a2 * y;
  695.              while (ptx < pty) {
  696.                ellipse_pt(ctrx,ctry,x++,y);
  697.                if (d<0)
  698.                  d+=incr1;
  699.                else {
  700.                  d+=incr2;
  701.                  incr2+=step1;
  702.                  y--;
  703.                  pty-=a2;
  704.                  }
  705.                ptx+=b2;
  706.                incr1+=step2;
  707.                incr2+=step2;
  708.                }
  709.  
  710.                                                                        10
  711.  
  712.  
  713.  
  714.                        GRAD Programmers' Reference Manual
  715.  
  716.              if (ptx == pty) ellipse_pt(ctrx,ctry,x,y);
  717.              y=0;
  718.              x=a;
  719.              d= ((a2 - (b2 * a)) << 1) + b2;
  720.              incr1= step1 + (a2 << 1);
  721.              incr2= step2 + step1 + (a2 << 1) - ((b2 * a) << 2);
  722.              pty=0;
  723.              ptx=b2 * x;
  724.              while (pty < ptx) {
  725.                ellipse_pt(ctrx,ctry,x,y++);
  726.                if (d<0)
  727.                  d+=incr1;
  728.                else {
  729.                  d+=incr2;
  730.                  incr2+=step2;
  731.                  x--;
  732.                  ptx-=b2;
  733.                  }
  734.                pty+=a2;
  735.                incr1+=step1;
  736.                incr2+=step1;
  737.                }
  738.              if (ptx==pty) ellipse_pt(ctrx,ctry,x,y);
  739.            }
  740.        
  741.        
  742.        7.3  Arc
  743.        
  744.             Program for Arc1  and Earc1 can be obtained by making simple
  745.        modification of the program  circle and ellipse  in the preceding
  746.        sections.  Arc2  and Earc2 are much more complicated. I use table
  747.        instead of using the sine and tangent function in  order to avoid
  748.        using  floating  arithmetic.  Moreover the  situation  is further
  749.        complicated by the fact that I do  not know  the exact coordinate
  750.        of the starting  and ending  point.  There are a  lot  of special
  751.        cases in the processing.  The consequence is that I use  a lot of
  752.        time to debug  the routines.  Therefore do not try to  modify the
  753.        Arc2 and Earc2 routines unless you know what you are doing.
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.                                                                        11
  776.  
  777.  
  778.  
  779.                        GRAD Programmers' Reference Manual
  780.  
  781.        8   Text Writing
  782.        
  783.             WriteStr  is  quite simple  so I will concentrate  on writec
  784.        here.
  785.             
  786.             In GRAD system,  there are two types of font  can be loaded.
  787.        They are fix size  character and  variable  size  characters. The
  788.        font table and the program  are  structure  in  such  a  way that
  789.        differences in processing are kept to a minimum. This is achieved
  790.        by using pointers to pointer to the desire information instead of
  791.        direct referencing.
  792.             
  793.             I am  not going to  describe  the  clipping  and  copying of
  794.        patterns to  the frame because  I  have  already  written  a more
  795.        efficient routine to do both of them at the same time. It will be
  796.        included in the next release in the near future.
  797.  
  798.  
  799.  
  800.  
  801.  
  802.  
  803.  
  804.  
  805.  
  806.  
  807.  
  808.  
  809.  
  810.  
  811.  
  812.  
  813.  
  814.  
  815.  
  816.  
  817.  
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824.  
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.                                                                        12
  841.  
  842.  
  843.  
  844.                        GRAD Programmers' Reference Manual
  845.  
  846.        9   Region Filling
  847.        
  848.             The routine below will  extend  from the given  point to the
  849.        left until it  encounters  a pixel  which  value  is  opposite to
  850.        blankv or left edge  of the frame  is reached.  The line is drawn
  851.        using  the style given in  pattern.  blankv  can either  be  0 or
  852.        0xffff but not any other value.
  853.            
  854.            xleft(x,y,blankv,pattern)
  855.            int x,y,blankv,pattern;
  856.            {
  857.              int *xyloc;
  858.              int loop;
  859.              unsigned int word, word2, temp, tempdot;
  860.            
  861.              unsigned int fr_read();
  862.            
  863.              xyloc=calcaddr(x,y);
  864.              word2=(word=fr_read(xyloc)) ^ blankv;
  865.              if (word2 & DOTVALUE[x & 0x0f]) return;
  866.            
  867.              word2=word2 & RIGHTWORD[(x & 0x0f) + 1];
  868.              if (word2) {
  869.                tempdot=exchange(DOTVALUE[x & 0x0f]);
  870.                word2=exchange(word2);
  871.                for (loop=(x & 0x0f)+1; !(word2 & tempdot);
  872.                    loop--, word2>>=1) ;
  873.                temp=LEFTWORD[loop] & RIGHTWORD[(x & 0x0f) + 1];
  874.                word2=(pattern & temp) & (word & (~temp));
  875.                fr_write(xyloc,word2);
  876.                return;
  877.              }
  878.              word2=(pattern & RIGHTWORD[(x & 0x0f)+1]) |
  879.                            (word & LEFTWORD[(x & 0x0f)+1]);
  880.              fr_write(xyloc,word2);
  881.              xyloc--; x-=16;
  882.              while(!((word=fr_read(xyloc))^blankv) && (x >= 0)) {
  883.                fr_write(xyloc,pattern);
  884.                x-=16;
  885.                xyloc--;
  886.              }
  887.              if (x>=0) {
  888.                word2=exchange(word ^ blankv);
  889.                for(loop=16; !(word2 & 0x01); loop--, word2>>=1) ;
  890.                word2=(pattern & LEFTWORD[loop]) |
  891.                              (word & RIGHTWORD[loop]);
  892.                fr_write(xyloc,word2);
  893.              }
  894.            }
  895.        
  896.             The XHLine in GRAD system will extend in both  direction and
  897.        the coordinates of  the end points  are returned.  XHLine  is the
  898.        basis for region filling. The algorithm for SolidFill is:
  899.             
  900.            1. execute XHLine using the starting coordinate.
  901.            2. if nothing can be drawn, return
  902.            3. otherwise put the left most coordinate and length on the
  903.               queue
  904.  
  905.                                                                        13
  906.  
  907.  
  908.  
  909.                        GRAD Programmers' Reference Manual
  910.  
  911.            4. fetch the first item on queue. the coordinates fetched is
  912.               the current location and the line starting from current
  913.               location is called the current line
  914.            5. go up 1 line (decrement y coordinate) and search in the
  915.               left direction
  916.            6. if a pixel in background state is found, XHLine is
  917.               executed and the left most coordinate and the length is
  918.               put on queue
  919.            7. the search continue until it is above the right most point
  920.               of current line.
  921.            8. go down 1 line from current location (increment y
  922.               coordinate by 1) and search to the left.
  923.            9. if a pixel in background state is found, XHLine is
  924.               executed and the left most coordinate and the length is
  925.               put on queue
  926.            10. the search continue until it is below the right most
  927.               point of current line.
  928.            11. if there is any item on queue, repeat process 4 to 11
  929.            
  930.             
  931.             Note that I use queue instead of  stack so  that  the region
  932.        filling routine gives a illusion of  filling in  all direction at
  933.        the  same time.  The memory for  the queue is  allocated from the
  934.        stack so it won't 'waste'  any memory when filling  functions are
  935.        not executed.
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943.  
  944.  
  945.  
  946.  
  947.  
  948.  
  949.  
  950.  
  951.  
  952.  
  953.  
  954.  
  955.  
  956.  
  957.  
  958.  
  959.  
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.                                                                        14
  971.  
  972.  
  973.  
  974.                        GRAD Programmers' Reference Manual
  975.  
  976.        10  Block Copy, Save and Load
  977.        
  978.             Block file  structure is  already  explained  in  the Users'
  979.        manual so  it  would not  be  repeated  here.  A  new  version of
  980.        BlockCopy, BlockSave and BlockLoad is written such that block can
  981.        be copied or loaded  to any  location.  They would be included in
  982.        the next release in the near future.
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997.  
  998.  
  999.  
  1000.  
  1001.  
  1002.  
  1003.  
  1004.  
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010.  
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.                                                                        15
  1036.  
  1037.  
  1038.  
  1039.                        GRAD Programmers' Reference Manual
  1040.  
  1041.        11  Writing Graphics Display Adapter Driver
  1042.        
  1043.             One basic requirement for a graphics adapter  in GRAD system
  1044.        is that the memory for each line must be in consecutive locations
  1045.        and the most significant bit of each byte is the left  most pixel
  1046.        of that  byte  when displayed.  The byte with lower  address in a
  1047.        line is  displayed on the  left.  Furthermore, the number of byte
  1048.        for each line must be even and the memory  in the  same line must
  1049.        be in  the same  bank if the graphics  display memory  is divided
  1050.        into banks.
  1051.             
  1052.             I shall discuss the writing of graphics adapter according to
  1053.        different cases.
  1054.             
  1055.        Case I:   All  graphics  display memory  can be  accessed without
  1056.                  changing any page  register  or  toggling  any software
  1057.                  switch.
  1058.             
  1059.             The modification  required  is quite  simple. Firstly change
  1060.        the  location  defined for _SCREEN in  calcaddr.asm.  Then change
  1061.        $calc  and downln  for  your  graphics  display  card.  Since the
  1062.        address  return  by  $calc is a  far address so  the offset value
  1063.        should be small enough such  that every  byte in the line  can be
  1064.        accessed without changing the segment value.
  1065.        
  1066.        Case II:  Graphics memory  is  divided into banks  but memory for
  1067.                  each line is in the same bank.
  1068.             
  1069.             Same as Case I and then change $or,  $and and $xor such that
  1070.        they  can change  to  appropriate bank  using information  in the
  1071.        segment value. phyaddr routine has to be written too. JLASER is a
  1072.        example for this case.
  1073.             
  1074.             
  1075.             
  1076.             Then you may need to  rewrite some  supporting routines such
  1077.        as settext and setgraph.
  1078.        
  1079.  
  1080.  
  1081.  
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091.  
  1092.  
  1093.  
  1094.  
  1095.  
  1096.  
  1097.  
  1098.  
  1099.  
  1100.                                                                        16
  1101.  
  1102.  
  1103.  
  1104.                        GRAD Programmers' Reference Manual
  1105.  
  1106.        12  Writing Printer Driver
  1107.        
  1108.             Information given in the users'  manual should be sufficient
  1109.        for  writing printer drivers  for  all  printer  providing  8 bit
  1110.        graphics mode.  In the section below, I shall describe the way to
  1111.        write drivers for 7 bit and 24 bit graphics mode printer.
  1112.             
  1113.             Firstly,   you  should  define  the  control   sequences  in
  1114.        prtcntl.c as described in the users' manual.
  1115.             
  1116.             For 7 bit graphics mode, change ndot in pframe.c from 8 to 7
  1117.        and then change prt in prtgc.asm so that the data can be send out
  1118.        properly.
  1119.             
  1120.             If you use a  24-pin  printer,  you  need  to  do  some more
  1121.        things. Firstly, change ndot to 24. You need to change the prt in
  1122.        prtgc such that 3  bytes in a row are generated. Inside prt,  you
  1123.        may use any registers except si and di unless you save them first
  1124.        and then restore them  before return.  Furthermore, if the length
  1125.        of data  graphics  are required  to  be  included  in the control
  1126.        sequence,  you may have  to  modify prtpc and  optprt in pframe.c
  1127.        and rmv0  in  prt.asm.  It is because the length  in  the control
  1128.        sequence should be the number of columns of graphics data instead
  1129.        of  the number  of  bytes.  You cannot divide the number  of data
  1130.        byte by  a factor  using the standard  features.  Furthermore the
  1131.        rmv0 only look for the last non-zero byte in the output data. You
  1132.        need to change either  rmv0  or optprt to ensure the length  is a
  1133.        multiple of 3.
  1134.             
  1135.             After making the changes, recompile all modified files.
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159.  
  1160.  
  1161.  
  1162.  
  1163.  
  1164.  
  1165.                                                                        17
  1166.  
  1167.  
  1168.  
  1169.                        GRAD Programmers' Reference Manual
  1170.  
  1171.        13  Hints on Porting to Other C Compiler or Other Machine
  1172.        
  1173.             To port GRAD  to other C  compiler or other system,  I think
  1174.        the most difficult part is the use far and huge  pointers and the
  1175.        large number of assembly routines.
  1176.             
  1177.             If the C compiler does not have  the far or  huge pointer or
  1178.        the architecture  of  the object  machine does  not need  to have
  1179.        different kinds of pointer,  the first thing you need to do is do
  1180.        eliminate  all those far and huge key words and the none standard
  1181.        function calls halloc and hfree.
  1182.             
  1183.             After that  rewrite calcaddr.asm  and plottype.asm  and then
  1184.        use the C routines supplied  in the documentation  to implement a
  1185.        simple system first.
  1186.             
  1187.             Rewriting  the assemble  routines will be  difficult but not
  1188.        impossible.  But in the initial implementation,  you should avoid
  1189.        the following functions:  Arc2, Earc2 and related portion in circ
  1190.        and Ell, SolidFill, PatternFill and XHLine, Line (use the version
  1191.        given in this manual instead), writec and WriteStr.
  1192.             
  1193.             Good Luck !
  1194.  
  1195.  
  1196.  
  1197.  
  1198.  
  1199.  
  1200.  
  1201.  
  1202.  
  1203.  
  1204.  
  1205.  
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.  
  1230.                                                                        18
  1231.  
  1232.  
  1233.